<template>
  <el-dialog v-model="isDialogVisible" @open="openDialog" @close="closeDialog" :style="{ height: props.dialogConfig.dialogHeight, width: props.dialogConfig.dialogWidth }">
    <template #header>
      <!-- 自定义标题 -->
      <slot name="header">标题</slot>
    </template>
    <div class="dialog-main">
      <el-form ref="dialogFormRef" :model="localFieldInfo" :rules="rules" label-width="80px" class="flex-form">
        <div v-for="field in props.fields" :key="field.prop" :style="{ width: field.width || '100%' }">
          <el-form-item :label="field.label" :prop="field.prop">
            <!-- 文本框部分 -->
            <template v-if="field.type === 'input'">
              <el-input v-model="localFieldInfo[field.prop]" :placeholder="field.placeholder" :readonly="field.readonly" :disabled="field.disabled" :show-password="field.isPassword" />
              <!-- 输入框后的按钮 -->
              <slot :name="'append-' + field.prop" v-if="field.showAppendSlot"></slot>
            </template>
            <!-- 下拉框部分 -->
            <template v-else-if="field.type === 'select'">
              <el-select v-model="localFieldInfo[field.prop]" :placeholder="field.placeholder" :readonly="field.readonly" :disabled="field.disabled">
                <el-option v-for="option in field.options" :key="option.value" :label="option.label" :value="option.value" />
              </el-select>
            </template>
            <!-- 复选框部分 -->
            <template v-else-if="field.type === 'checkbox'">
              <el-checkbox-group v-model="localFieldInfo[field.prop]">
                <el-checkbox v-for="checkbox in field.checkboxes" :key="checkbox.label" :label="checkbox.label" />
              </el-checkbox-group>
            </template>
            <!-- 单选框部分 -->
            <template v-else-if="field.type === 'radio'">
              <el-radio-group v-model.number="localFieldInfo[field.prop]">
                <el-radio v-for="radio in field.radios" :key="radio.label" :label="radio.label">{{ radio.name }}</el-radio>
              </el-radio-group>
            </template>
          </el-form-item>
        </div>
      </el-form>
    </div>
    <template #footer>
      <!-- 自定义页脚(已将表单信息和关闭弹窗函数暴露) -->
      <slot name="footer">
        <el-button @click="submitForm">提交</el-button>
        <el-button @click="closeDialog">关闭</el-button>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup>
import { nextTick, ref, watch } from 'vue'
import { useCounterStore } from '@/stores/counter.js'
/* defineProps 父传子 */
const props = defineProps({
  dialogConfig: {
    type: Object,
    default: () => ({
      dialogHeight: '500px',
      dialogWidth: '400px'
    })
  },
  // 表单内容
  fields: {
    type: Array,
    default: () => [
      { type: 'input', prop: 'idCard', label: '用户名' },
      { type: 'input', prop: 'mobilePhone', label: '密码', isPassword: true },
      { prop: 'email', label: '邮箱', type: 'input' },
      {
        type: 'checkbox',
        prop: 'checkbox',
        label: '复选框',
        checkboxes: [{ label: '选项1' }, { label: '选项2' }]
      },
      {
        type: 'radio',
        prop: 'radio',
        label: '单选框',
        radios: [{ label: '1', name: '选项1' }, { label: '选项2' }]
      }
    ]
  },
  // 父组件传的默认值
  fieldInfo: {
    type: Object,
    default: () => ({ idCard: '5105', mobilePhone: '123', email: '@qq.com', checkbox: ['选项1'], radio: '1' })
  },
  // 自定义规则
  rules: {
    type: Object,
    default: () => ({
      idCard: [{ required: true, message: '需要填写该项', trigger: 'blur' }],
      personName: [{ required: true, message: '需要填写该项', trigger: 'blur' }],
      typeName: [{ required: true, message: '需要填写该项', trigger: 'blur' }]
    })
  }
})
/* 本界面 */
const localFieldInfo = ref({ ...props.fieldInfo }) // 包装fieldInfo使其成为响应式对象
const dialogFormRef = ref(null) // 表单ref响应式对象
const isDialogVisible = ref(false) // 弹窗是否显示
const counterStore = useCounterStore() // 从stores中创建实例
// 监听fieldInfo的变化,实时更改
watch(
  () => props.fieldInfo,
  (newValue) => {
    localFieldInfo.value = { ...newValue }
  },
  { deep: true }
)
// 提交表单数据
const submitForm = async () => {
  try {
    // 使用封装的方法进行表单验证
    await counterStore.validateForm(dialogFormRef.value)
    // 返回表单内容
    return localFieldInfo.value
  } catch (error) {
    // 处理表单验证失败的逻辑
    // console.error(error.message)
    return false
  }
}
// 初始化表单
const resetFieldInfo = () => {
  dialogFormRef.value.resetFields() // 将表单恢复成初始状态
}

/* defineExpose 子传父的方法 */
// 开启/关闭弹窗
const openDialog = () => {
  isDialogVisible.value = true
}
const closeDialog = () => {
  isDialogVisible.value = false
  nextTick()
  resetFieldInfo()
}
defineExpose({
  submitForm,
  openDialog,
  closeDialog,
  resetFieldInfo
})
</script>

<style scoped>
.dialog-main {
  padding: 20px;
}
.flex-form {
  padding-top: 20px;
  display: flex;
  flex-wrap: wrap; /* 允许表单项换行 */
  align-items: flex-start; /* 对齐表单项 */
}
</style>
